#ifndef __SYMBOL_H__
#define __SYMBOL_H__

#include "base.h"
#include "src.h"
#include "token.h"
#include "any.h"

enum 
{ 
	SK_Tag,    SK_TypedefName, SK_EnumConstant, SK_Constant, SK_Variable, SK_Temp,
	SK_Offset, SK_String,      SK_Label,        SK_Function, SK_Register
};

struct symbol_t
{
    int kind;
    char *name;
    char *aname;
    type_t* ty;
    int level;
    int sclass;
    int ref;
    int defined   : 1;
    int addressed : 1;
    int needwb    : 1;
    int unused    : 29;
    any_t val;
    struct symbol_t *reg;
    struct symbol_t *link;
    struct symbol_t *next;
    location_t loc;
};

/**
	struct valueDef and struct valueUse
		are used for DU list .
	Here definition is assignment to a variable just like
		t1 = b + c;	...>>   defition of t1,  use of b and c.
					t1 is a temporary variable.
	Buf in UCC, we never track a named variable 's definition
		a  = b + c;	-----
 */
/*  dst = src1  op 	src2,  the definition of a symbol */
struct value_def_t
{
	symbol_t* dst;
	int op;
	symbol_t* src1;
	symbol_t* src2;
	struct basic_block_t* ownBB;
	struct value_def_t *link;
};
/* the use of a definition */
struct value_use_t
{
	value_def_t* def;
	value_use_t* next;
};

struct variable_symbol_t: public symbol_t
{
	struct init_data_t* idata;
	value_def_t* def;
	value_use_t* uses;
	int offset;
};

struct function_symbol_t : public symbol_t
{
	symbol_t* params;
	symbol_t* locals;
	symbol_t* *lastv;
	int nbblock;
	basic_block_t* entryBB;
	basic_block_t* exitBB;
	value_def_t* valNumTable[16];
};

typedef struct table
{
	symbol_t *buckets;
	int level;
	struct table *outer;
} *Table;

extern int g_cur_level;

#endif  // __SYMBOL_H__
